#include "net.h"

int main(int argc, const char *argv[])
{
	//socket
	int socketfd = socket(AF_INET, SOCK_STREAM, 0);
	if (socketfd < 0)
	{
		perror("socket");
		return -1;
	}
	//bind
	int b_reuse = 1;
	setsockopt(socketfd, SOL_SOCKET, SO_REUSEADDR, &b_reuse, sizeof(int));
	struct sockaddr_in sin;
	bzero(&sin, sizeof(sin));
	sin.sin_family = AF_INET;
	sin.sin_port = htons(SERVER_PORT);
	sin.sin_addr.s_addr = htonl(INADDR_ANY);
	int bindret = bind(socketfd, (struct sockaddr *)&sin, sizeof(sin));
	if (bindret < 0)
	{
		perror("bind");
		return -1;
	}
	//listen
	int listenfd = listen(socketfd, BACKLOG);
	if (listenfd < 0)
	{
		perror("listen");
		return -1;
	}
	//select
	fd_set rset, allset;
	int maxfd = -1;
	int clientfd, newfd;
	char buf[128], resp_buf[138];
	int client[FD_SETSIZE];
	int i = 0, maxi;
	int readret, writeret;
	maxfd = socketfd;
	FD_ZERO(&allset);
	FD_SET(socketfd, &allset);
	while (1)
	{
		rset = allset;

		struct timeval tout;
		tout.tv_sec = 5;
		tout.tv_usec = 0;
		select(maxfd + 1, &rset, NULL, NULL, &tout);

	//if connect success,connect
		if (FD_ISSET(socketfd, &rset))
		{
			struct sockaddr_in cin;
			socklen_t addrlen = sizeof(cin);
			newfd = accept(socketfd, (struct sockaddr *)&cin, &addrlen);
			//save client fd
			if (i == FD_SETSIZE)
			{
				printf("too many clients\n");
				return -1;
			}
			client[i] = newfd;
			maxi = i;
			i++;
			//add newfd into rset, update maxfd
			FD_SET(newfd, &allset);
			if (newfd > maxfd)
				maxfd = newfd;
		}
		//check client for data
		for (i = 0; i <= maxi; i++)
		{
			if ((clientfd = client[i]) < 0)
				continue;
			if (FD_ISSET(clientfd, &rset))
			{
				bzero(buf, 128);
				do {
					readret = read(clientfd, buf, 127);
				}while(readret < 0 && EINTR == errno);
				if (!readret)
				{
					close(clientfd);
					FD_CLR(clientfd, &allset);
					break;
				}
				printf("Receive data: %s\n", buf);

				//quit when client send quit
				if (!strncasecmp(buf, QUIT, strlen(QUIT)))
				{
					printf("Client(fd = %d) is exiting!\n", clientfd);
					close(clientfd);
					FD_CLR(clientfd, &allset);
					break;
				}

				//respond to client
				bzero(resp_buf, 138);

				strncpy(resp_buf, SERV_RESP_STR, strlen(SERV_RESP_STR));
				strcat(resp_buf, buf); 
				do {
					writeret = write(clientfd, resp_buf, strlen(resp_buf));
				}while(writeret < 0 && EINTR == errno);
				
				//if (--nready <= 0)
				//	break;
			}
		}

	}
	return 0;
}
